package com.ciaojian.miniapp.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.http.HttpUtil;
import com.ciaojian.core.util.ApplicationContextHelper;
import com.ciaojian.miniapp.enums.MethodType;
import com.ciaojian.miniapp.enums.MiniAppApiType;
import com.ciaojian.miniapp.model.request.AccessToken;
import com.ciaojian.miniapp.model.request.BaseRequest;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.HashMap;
import java.util.Map;

/**
 * 请求工具
 *
 * @author Atlakyn
 */
public class RequestUtil {
    /**
     * 执行请求
     *
     * @param type     接口枚举
     * @param params   参数
     * @param response 返回类型
     * @return 请求结果
     */
    public static <T> T execution(MiniAppApiType type, Object params, Class<T> response) throws JsonProcessingException {
        return execution(type, params, true, response);
    }


    /**
     * 执行请求
     *
     * @return 请求结果
     */
    public static <T> T execution(MiniAppApiType type, Object params, Boolean requireToken, Class<T> clazz) throws JsonProcessingException {
        MethodType methodType = type.getMethodType();
        // 请求地址
        String url = type.getUrl();
        if (requireToken) {
            url = url.concat("?access_token=" + getAccessToken());
        }
        // 请求结果
        T t = null;
        if (methodType.equals(MethodType.GET)) {
            t = doGet(url, (Map<String, Object>) params, clazz);
        }
        if (methodType.equals(MethodType.POST)) {
            if (params instanceof Map) {
                t = doPost(url, (HashMap<String, Object>) params, clazz);
            }
            if (params instanceof String) {
                t = doPost(url, params.toString(), clazz);
            }
            if (params instanceof Object) {
                Map<String, Object> map = BeanUtil.beanToMap(params);
                t = doPost(url, map, clazz);
            }
        }
        return t;
    }

    /**
     * 执行请求
     *
     * @param token 传入 token
     * @return 请求结果
     */
    public static <T> T execution(MiniAppApiType type, Object params, String token, Class<T> clazz) throws JsonProcessingException {
        MethodType methodType = type.getMethodType();
        // 请求地址
        String url = type.getUrl();
        url = url.concat("?access_token=" + token);
        // 请求结果
        T t = null;
        if (methodType.equals(MethodType.GET)) {
            t = doGet(url, (Map<String, Object>) params, clazz);
        }
        if (methodType.equals(MethodType.POST)) {
            if (params instanceof Map) {
                t = doPost(url, (HashMap<String, Object>) params, clazz);
            }
            if (params instanceof String) {
                t = doPost(url, params.toString(), clazz);
            }
        }
        return t;
    }

    /**
     * 获取 access_token
     *
     * @return 微信返回的 access_token
     */
    private static String getAccessToken() throws JsonProcessingException {
        AccessToken accessToken = ApplicationContextHelper.getBean(AccessToken.class);
        Map map = execution(MiniAppApiType.ACCESS_TOKEN, BeanUtil.beanToMap(accessToken), false, Map.class);

        if (map != null) {
            return String.valueOf(map.get("access_token"));
        }
        return null;
    }

    static Map<String, Object> bean2Map(BaseRequest baseRequest) {
        return BeanUtil.beanToMap(baseRequest);
    }

    private static <T> T doGet(String url, Map<String, Object> params, Class<T> t) throws JsonProcessingException {
        String result = HttpUtil.get(url, params);
        return new ObjectMapper().readValue(result, t);
    }

    private static <T> T doPost(String url, Map<String, Object> params, Class<T> t) throws JsonProcessingException {
        String result = HttpUtil.post(url, params);
        String a = "{\"code\":\"INVALID_REQUEST\",\"message\":\"Http头Content-Type值必须为application/json\"}";
        return new ObjectMapper().readValue(a, t);
    }

    private static <T> T doPost(String url, String params, Class<T> t) throws JsonProcessingException {
        String result = HttpUtil.post(url, params);
        return new ObjectMapper().readValue(result, t);
    }
}
